package com.ccx.demo.business.code.service;

import com.ccx.demo.business.code.dao.jpa.CodeExampleRepository;
import com.ccx.demo.business.code.dto.TabCodeExampleInsertDTO;
import com.ccx.demo.business.code.dto.TabCodeExampleUpdateDTO;
import com.ccx.demo.business.code.entity.QTabCodeExample;
import com.ccx.demo.business.code.entity.TabCodeExample;
import com.ccx.demo.business.code.enums.DemoStatus;
import com.ccx.demo.business.code.vo.TabCodeExampleJpaExistsVO;
import com.ccx.demo.business.code.vo.TabCodeExampleVO;
import com.ccx.demo.business.user.entity.QTabUser;
import com.ccx.demo.business.user.entity.TabUser;
import com.ccx.demo.business.user.service.UserService;
import com.google.common.collect.Sets;
import com.querydsl.core.QueryResults;
import com.support.mvc.entity.IWhere;
import com.support.mvc.entity.base.Page;
import com.support.mvc.exception.DeleteRowsException;
import com.support.mvc.exception.UpdateRowsException;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.validation.annotation.Validated;

import javax.validation.Valid;
import javax.validation.constraints.*;
import java.util.*;
import java.util.function.Consumer;
import java.util.stream.Collectors;
import java.util.stream.Stream;

//import static com.ccx.demo.config.init.AppInit.getCacheManager; // 若使用缓存需要解开代码

/**
 * 服务接口实现类：测试案例表
 *
 * @author 谢长春 on 2022-02-16 V20220301
 */
@Slf4j
@Service
@Validated
@RequiredArgsConstructor
public class CodeExampleService
//      , ITabCodeExampleCache
{
    private final CodeExampleRepository repository;
    private final UserService userService;
//     /** // 若使用缓存需要解开代码
//      * 获取当前缓存管理器，用于代码控制缓存
//      *
//      * @return {@link Cache}
//      */
//     public Cache getCache() {
//         return Objects.requireNonNull(getCacheManager().getCache(CACHE_ROW_BY_ID), "未获取到缓存管理对象:".concat(CACHE_ROW_BY_ID));
//     }
//
//     /** // 若使用缓存需要解开代码
//      * 清除多个 key 对应的缓存
//      *
//      * @param ids {@link TabCodeExample#getId()}
//      */
//     public void clearKeys(final Collection<Long> ids) {
//         ids.stream().distinct().forEach(id -> getCache().evict(id));
//     }

    /**
     * 新增 测试案例表
     *
     * @param dto    {@link TabCodeExampleInsertDTO} 实体对象
     * @param userId {@link Long} 操作用户ID
     * @return {@link TabCodeExample} 实体对象
     */
    @Transactional(rollbackFor = Exception.class)
    public @NotNull(message = "返回值不能为null") TabCodeExample insert(
            @Valid @NotNull(message = "【dto】不能为null") final TabCodeExampleInsertDTO dto
            , @NotNull(message = "【userId】不能为null") final Long userId) {
        final TabCodeExample obj = new TabCodeExample();
        BeanUtils.copyProperties(dto, obj);
        return repository.insert(userId, obj);
    }

    /**
     * 批量新增 测试案例表
     *
     * @param list   {@link List<TabCodeExampleInsertDTO>}  实体对象集合
     * @param userId {@link Long} 操作用户ID
     * @return List<TabCodeExample> 实体对象集合
     */
    @Transactional(rollbackFor = Exception.class)
    public @NotNull(message = "返回值不能为null") List<TabCodeExample> insert(
            @NotEmpty(message = "【list】不能为空") final List<@Valid @NotNull TabCodeExampleInsertDTO> list
            , @NotNull(message = "【userId】不能为null") final Long userId) {
        return repository.insert(userId, list.stream()
                .map(dto -> {
                    final TabCodeExample obj = new TabCodeExample();
                    BeanUtils.copyProperties(dto, obj);
                    return obj;
                })
                .collect(Collectors.toList())
        );
    }

    /**
     * 更新 测试案例表 ；
     *
     * @param id     {@link Long} 数据ID
     * @param userId {@link Long} 操作用户ID
     * @param dto    {@link TabCodeExampleUpdateDTO} 实体对象
     */
    @Transactional(rollbackFor = Exception.class)
    public void update(
            @NotNull(message = "【id】不能为null") @Positive(message = "【id】必须大于0") final Long id
            , @NotNull(message = "【userId】不能为null") final Long userId
            , @Valid @NotNull(message = "【dto】不能为null") final TabCodeExampleUpdateDTO dto) {
        final TabCodeExample obj = new TabCodeExample();
        BeanUtils.copyProperties(dto, obj);
        UpdateRowsException.asserts(repository.update(id, userId, obj));
    }

    /**
     * 测试案例表 按ID删除，物理删除
     *
     * @param id     {@link Long} 数据ID
     * @param userId {@link Long} 操作用户ID
     */
    @Transactional(rollbackFor = Exception.class)
    public void deleteById(
            @NotNull(message = "【id】不能为null") @Positive(message = "【id】必须大于0") final Long id
            , @NotNull(message = "【userId】不能为null") final Long userId) {
        DeleteRowsException.asserts(repository.deleteById(id, userId));
    }

    /**
     * 测试案例表 按 id+updateTime 删除，物理删除
     *
     * @param id         {@link Long} 数据ID
     * @param updateTime {@link String} 最后一次更新时间
     * @param userId     {@link Long} 操作用户ID
     */
    @Transactional(rollbackFor = Exception.class)
    public void deleteById(
            @NotNull(message = "【id】不能为null") @Positive(message = "【id】必须大于0") final Long id
            , @NotBlank(message = "【updateTime】不能为null") @Size(min = 17, max = 17, message = "【updateTime】必须是 17 位") final String updateTime
            , @NotNull(message = "【userId】不能为null") final Long userId
    ) {
        DeleteRowsException.asserts(repository.deleteById(id, updateTime, userId));
    }

    /**
     * 测试案例表 按ID删除，物理删除
     *
     * @param ids    {@link Set<Long>} 数据ID
     * @param userId {@link Long} 操作用户ID
     */
    @Transactional(rollbackFor = Exception.class)
    public void deleteByIds(
            @NotEmpty(message = "【ids】不能为空") final Set<@Valid @NotNull Long> ids
            , @NotNull(message = "【userId】不能为null") final Long userId) {
        DeleteRowsException.asserts(repository.deleteByIds(ids, userId), ids.size());
        // clearKeys(ids); // 若使用缓存需要解开代码
    }

    /**
     * 测试案例表 按 id+updateTime 删除，物理删除
     *
     * @param ids         {@link Set<Long>} 数据ID
     * @param updateTimes {@link Set<String>} 最后一次更新时间
     * @param userId      {@link Long} 操作用户ID
     */
    @Transactional(rollbackFor = Exception.class)
    public void deleteByIds(
            @NotEmpty(message = "【ids】不能为空") final Set<@Valid @NotNull Long> ids
            , @NotEmpty(message = "【updateTimes】不能为空") final Set<@Valid @NotBlank String> updateTimes
            , @NotNull(message = "【userId】不能为null") final Long userId
    ) {
        DeleteRowsException.asserts(repository.deleteByIds(ids, updateTimes, userId), ids.size());
        // clearKeys(ids); // 若使用缓存需要解开代码
    }


    /**
     * 测试案例表 按ID删除，逻辑删除
     *
     * @param id     {@link Long} 数据ID
     * @param userId {@link Long} 操作用户ID
     */
    @Transactional(rollbackFor = Exception.class)
    public void markDeleteById(
            @NotNull(message = "【id】不能为null") @Positive(message = "【id】必须大于0") final Long id
            , @NotNull(message = "【userId】不能为null") final Long userId) {
        DeleteRowsException.asserts(repository.markDeleteById(id, userId));
    }

    /**
     * 测试案例表 按 id+updateTime 删除，逻辑删除
     *
     * @param id         {@link Long} 数据ID
     * @param updateTime {@link String} 最后一次更新时间
     * @param userId     {@link Long} 操作用户ID
     */
    @Transactional(rollbackFor = Exception.class)
    public void markDeleteById(
            @NotNull(message = "【id】不能为null") @Positive(message = "【id】必须大于0") final Long id
            , @NotBlank(message = "【updateTime】不能为null") @Size(min = 17, max = 17, message = "【updateTime】必须是 17 位") final String updateTime
            , @NotNull(message = "【userId】不能为null") final Long userId
    ) {
        DeleteRowsException.asserts(repository.markDeleteById(id, updateTime, userId));
    }

    /**
     * 测试案例表 按ID删除，逻辑删除
     *
     * @param ids    {@link Set<Long>} 数据ID
     * @param userId {@link Long} 操作用户ID
     */
    @Transactional(rollbackFor = Exception.class)
    public void markDeleteByIds(
            @NotEmpty(message = "【ids】不能为空") final Set<@Valid @NotNull Long> ids
            , @NotNull(message = "【userId】不能为null") final Long userId) {
        DeleteRowsException.asserts(repository.markDeleteByIds(ids, userId), ids.size());
        // clearKeys(ids); // 若使用缓存需要解开代码
    }

    /**
     * 测试案例表 按 id+updateTime 删除，逻辑删除
     *
     * @param ids         {@link Set<Long>} 数据ID
     * @param updateTimes {@link Set<String>} 最后一次更新时间
     * @param userId      {@link Long} 操作用户ID
     */
    @Transactional(rollbackFor = Exception.class)
    public void markDeleteByIds(
            @NotEmpty(message = "【ids】不能为空") final Set<@Valid @NotNull Long> ids
            , @NotEmpty(message = "【updateTimes】不能为空") final Set<@Valid @NotBlank String> updateTimes
            , @NotNull(message = "【userId】不能为null") final Long userId
    ) {
        DeleteRowsException.asserts(repository.markDeleteByIds(ids, updateTimes, userId), ids.size());
        // clearKeys(ids); // 若使用缓存需要解开代码
    }

    /**
     * 测试案例表 按ID查询对象，注意这里可能有 deleted 为 YES 的数据
     *
     * @param id {@link Long} 数据ID
     * @return {@link Optional< TabCodeExample >} 实体对象
     */
    @Transactional(readOnly = true, propagation = Propagation.NOT_SUPPORTED)
    public Optional<TabCodeExample> findById(final Long id) {
        if (Objects.isNull(id) || id < 1) {
            return Optional.empty();
        }
        return repository.findById(id)
                .map(TabCodeExample::cloneObject); // 必须要 clone ，如果直接对持久化对象调用 set 方法，会触发更新动作
//         return Optional.ofNullable(repository.findCacheById(id)).map(TabCodeExample::cloneObject); // 若使用缓存需要解开代码
    }

    /**
     * 填充用户昵称
     *
     * @param list List<TabCodeExample>
     */
    private <T extends TabCodeExample> void fillUserNickname(final List<T> list) {
        if (list.isEmpty()) {
            return;
        }
        final Map<Long, TabUser> userMap = userService.mapByIds(list.stream()
                .flatMap(row -> Stream.of(row.getCreateUserId(), row.getUpdateUserId()))
                .filter(Objects::nonNull)
                .collect(Collectors.toSet())
        );
        list.forEach(row -> {
            Optional.ofNullable(userMap.get(row.getCreateUserId())).ifPresent(user -> {
                row.setCreateUserNickname(user.getNickname());
            });
            Optional.ofNullable(userMap.get(row.getUpdateUserId())).ifPresent(user -> {
                row.setUpdateUserNickname(user.getNickname());
            });
        });
    }

    /**
     * 测试案例表 按条件分页查询列表
     *
     * @param condition {@link TabCodeExample} 查询条件
     * @param page      {@link Page} 分页排序集合
     * @return {@link QueryResults< TabCodeExample >} 分页对象
     */
    @Transactional(readOnly = true, propagation = Propagation.NOT_SUPPORTED)
    public @NotNull(message = "返回值不能为null") QueryResults<TabCodeExample> page(
            @NotNull(message = "【condition】不能为null") final TabCodeExample condition,
            @NotNull(message = "【page】不能为null") @Valid final Page page) {
        final QueryResults<TabCodeExample> queryResults = repository.page(condition, page);
        if (queryResults.isEmpty()) {
            return QueryResults.emptyResults();
        }
        fillUserNickname(queryResults.getResults());
        return queryResults;
    }

    /**
     * 测试案例表 按条件查询列表
     *
     * @param condition {@link TabCodeExample} 查询条件
     * @return {@link List<TabCodeExample>} 结果集合
     */
    @Transactional(readOnly = true, propagation = Propagation.NOT_SUPPORTED)
    public @NotNull(message = "返回值不能为null") List<TabCodeExample> list(
            @NotNull(message = "【condition】不能为null") final TabCodeExample condition) {
        final List<TabCodeExample> list = repository.list(condition);
        if (list.isEmpty()) {
            return Collections.emptyList();
        }
        fillUserNickname(list);
        return list;
    }


    /**
     * 测试案例表 按 id 批量查询列表，注意这里可能有 deleted 为 true 的数据
     *
     * @param ids {@link Long}  数据 id 集合
     * @return {@link List< TabCodeExample >} 结果集合
     */
    @Transactional(readOnly = true, propagation = Propagation.NOT_SUPPORTED)
    public @NotNull(message = "返回值不能为null") List<TabCodeExample> listByIds(final Collection<Long> ids) {
        if (CollectionUtils.isEmpty(ids)) {
            return Collections.emptyList();
        }
        return repository.listByIds(ids);
    }

    /**
     * 测试案例表 按 id 批量查询列表，返回 map ， key 为数据 id ， 注意这里可能有 deleted 为 true 的数据
     *
     * @param ids {@link Long} 数据 id 集合
     * @return {@link List< TabCodeExample >} 结果集合
     */
    @Transactional(readOnly = true, propagation = Propagation.NOT_SUPPORTED)
    public @NotNull(message = "返回值不能为null") Map<Long, TabCodeExample> mapByIds(final Set<Long> ids) {
        if (CollectionUtils.isEmpty(ids)) {
            return Collections.emptyMap();
        }
        return repository.mapByIds(ids);
    }

    /**
     * 列表查询，投影到 VO 类
     *
     * @param condition {@link TabCodeExampleVO}
     * @return {@link QueryResults<TabCodeExampleVO>}
     */
    public @NotNull(message = "返回值不能为null") List<TabCodeExampleVO> listVO(
            @NotNull(message = "【condition】不能为null") final TabCodeExample condition
    ) {
        final List<TabCodeExampleVO> list = repository.list(condition, TabCodeExampleVO.class);
        if (list.isEmpty()) {
            return Collections.emptyList();
        }
        fillUserNickname(list);
        return list;
    }

    /**
     * 分页查询，投影到 VO 类
     *
     * @param condition {@link TabCodeExampleVO}
     * @param page      {@link TabCodeExampleVO}
     * @return {@link QueryResults<TabCodeExampleVO>}
     */
    public @NotNull(message = "返回值不能为null") QueryResults<TabCodeExampleVO> pageVO(
            @NotNull(message = "【condition】不能为null") final TabCodeExample condition,
            @NotNull(message = "【page】不能为null") @Valid final Page page
    ) {
//        QueryResults<TabCodeExampleVO> page1 = repository.page(
//                condition,
//                page,
//                TabCodeExampleVO.class
//                , QTabCodeExample.tabCodeExample.id
//                , QTabCodeExample.tabCodeExample.name
//                , QTabCodeExample.tabCodeExample.createUserId
//                , QTabCodeExample.tabCodeExample.updateUserId
//        );
//
//        QueryResults<TabCodeExample> page2 = repository.page(
//                condition,
//                page
//                , QTabCodeExample.tabCodeExample.id
//                , QTabCodeExample.tabCodeExample.name
//                , QTabCodeExample.tabCodeExample.createUserId
//                , QTabCodeExample.tabCodeExample.updateUserId
//        );
        final QueryResults<TabCodeExampleVO> queryResults = repository.page(condition, page, TabCodeExampleVO.class);
        if (queryResults.isEmpty()) {
            return QueryResults.emptyResults();
        }
        fillUserNickname(queryResults.getResults());
        return queryResults;
    }

    /**
     * 连表查询，基于父类扩展查询字段和查询条件，只返回部分字段
     *
     * @param condition {@link TabCodeExampleVO}
     * @param page      {@link TabCodeExampleVO}
     * @return {@link QueryResults<TabCodeExampleVO>}
     */
    public @NotNull(message = "返回值不能为null") QueryResults<TabCodeExampleVO> pageSimpleJoinTabUser(
            @NotNull(message = "【condition】不能为null") final TabCodeExample condition,
            @NotNull(message = "【page】不能为null") @Valid final Page page
    ) {
        QTabCodeExample qTabCodeExample = QTabCodeExample.tabCodeExample;
//        { // 优化版：分批
//            QueryResults<TabCodeExampleVO> queryResults = repository.page(
//                    condition,
//                    page,
//                    TabCodeExampleVO.class
//                    , qTabCodeExample.id
//                    , qTabCodeExample.name
//                    , qTabCodeExample.createUserId
//            );
//            if (queryResults.isEmpty()) {
//                return QueryResults.emptyResults();
//            }
//            final Map<Long, TabUser> userMap = userService.mapByIds(
//                    queryResults.getResults().stream()
////                            .map(TabCodeExample::getCreateUserId)
//                            .flatMap(row -> Stream.of(row.getCreateUserId(), row.getUpdateUserId()))
//                            .filter(Objects::nonNull)
//                            .collect(Collectors.toSet())
//            );
//            queryResults.getResults().forEach(row -> {
//                Optional.ofNullable(userMap.get(row.getCreateUserId())).ifPresent(user -> {
//                    row.setCreateUserNickname(user.getNickname());
//                    row.setRoles(user.getRoles());
//                });
//                Optional.ofNullable(userMap.get(row.getUpdateUserId())).ifPresent(user -> {
//                    row.setUpdateUserNickname(user.getNickname());
//                    row.setRoles(user.getRoles());
//                });
//            });
//        }

        QTabUser qTabUser = QTabUser.tabUser;
        return repository.pageJoinTabUser(
                condition,
                page,
                TabCodeExampleVO.class,
                qTabUser.username,
                qTabUser.roles,
                qTabCodeExample.id,
                qTabCodeExample.name
        );
    }

    /**
     * 连表查询，基于父类扩展查询字段和查询条件，返回主表全部字段
     *
     * @param condition {@link TabCodeExampleVO}
     * @param page      {@link TabCodeExampleVO}
     * @return {@link QueryResults<TabCodeExampleVO>}
     */
    public @NotNull(message = "返回值不能为null") QueryResults<TabCodeExampleVO> pageFullJoinTabUser(
            @NotNull(message = "【condition】不能为null") final TabCodeExample condition,
            @NotNull(message = "【page】不能为null") @Valid final Page page
    ) {
        QTabUser qTabUser = QTabUser.tabUser;
        return repository.pageJoinTabUser(
                condition,
                page,
                TabCodeExampleVO.class,
                TabCodeExample.allColumnAppends(
                        qTabUser.username,
                        qTabUser.roles
                )
        );
    }

    public void mapByIds(final TabCodeExample condition, final Consumer<List<TabCodeExample>> listConsumer) {
        {
            Map<Long, TabCodeExample> map = repository.mapByIds(Sets.newHashSet(1L, 2L));
        }
        { // 优化，只取需要的字段
            Map<Long, TabCodeExample> map = repository.mapByIds(
                    Sets.newHashSet(1L, 2L)
                    , QTabCodeExample.tabCodeExample.name
                    , QTabCodeExample.tabCodeExample.content
                    , QTabCodeExample.tabCodeExample.createTime
            );
        }
        {
            Map<Long, String> map = repository.mapByIds(
                    Sets.newHashSet(1L, 2L)
                    , QTabCodeExample.tabCodeExample.name
            );
            Map<Long, Boolean> map2 = repository.mapByIds(
                    Sets.newHashSet(1L, 2L)
                    , QTabCodeExample.tabCodeExample.deleted
            );
/*
SELECT
     tab_code_example.id
   , tab_code_example.name
   , tab_code_example.createUserId
   , createUser.nickname createUserNickname
   , tab_code_example.updateUserId
   , updateUser.nickname updateUserNickname
FROM tab_code_example
LEFT JOIN tab_user createUser ON createUser.id = tab_code_example.createUserId
LEFT JOIN tab_user updateUser ON updateUser.id = tab_code_example.updateUserId
;
*/
//            QueryResults<TabCodeExampleVO> page = repository.page(new TabCodeExample(), Page.defaultPage(), TabCodeExampleVO.class);
//            if (page.isEmpty())  {
//                return QueryResults.emptyResults();
//            }
//            Map<Long, String> userNicknameMap = repository.mapByIds(
//                    page.getResults().stream()
//                            .flatMap(row -> Stream.of(row.getCreateUserId(), row.getUpdateUserId()))
//                            .filter(Objects::nonNull)
//                            .collect(Collectors.toSet())
//                    , QTabCodeExample.tabCodeExample.name
//            );
//            page.getResults().forEach(row -> {
//                row.setCreateUserNickname(userNicknameMap.get(row.getCreateUserId()));
//                row.setUpdateUserNickname(userNicknameMap.get(row.getUpdateUserId()));
//            });
        }
        {
            Map<Long, TabCodeExampleVO> map = repository.mapByIds(
                    Sets.newHashSet(1L, 2L)
                    , TabCodeExampleVO.class
                    , QTabCodeExample.tabCodeExample.name
                    , QTabCodeExample.tabCodeExample.createUserId
                    , QTabCodeExample.tabCodeExample.content
            );
        }
    }

    public void forEachCsv(final TabCodeExample condition, final Consumer<List<TabCodeExample>> listConsumer) {
        repository.forEach(
                listConsumer
                , condition.where()
                , QTabCodeExample.tabCodeExample.id
                , QTabCodeExample.tabCodeExample.name
                , QTabCodeExample.tabCodeExample.amount
                , QTabCodeExample.tabCodeExample.status
                , QTabCodeExample.tabCodeExample.createTime
                , QTabCodeExample.tabCodeExample.createUserId
                , QTabCodeExample.tabCodeExample.updateUserId
                , QTabCodeExample.tabCodeExample.updateTime
        );
    }

    public void forEachExample1(final Consumer<List<TabCodeExample>> listConsumer) {
        final TabCodeExample condition = new TabCodeExample();
        condition.setStatus(DemoStatus.SUCCESS);
        repository.forEach(
                listConsumer
                , condition.where()
                , QTabCodeExample.tabCodeExample.id
//                , QTabCodeExample.tabCodeExample.name
//                , QTabCodeExample.tabCodeExample.content
        );
    }

    public void forEachExample2(final TabCodeExample condition, final Consumer<List<TabCodeExample>> listConsumer) {
        repository.forEach(
                listConsumer
                , condition.where()
                , QTabCodeExample.tabCodeExample.id
                , QTabCodeExample.tabCodeExample.name
                , QTabCodeExample.tabCodeExample.content
        );
    }

    public void pageTest() {
        {
            final TabCodeExampleVO condition = new TabCodeExampleVO();
            QueryResults<TabCodeExampleVO> queryResults = repository.page(
                    condition
                    , Page.defaultPage()
                    , TabCodeExampleVO.class
//                    , TabCodeExample.allColumnAppends(
//                            QTabUser.tabUser.nickname
//                    )
            );
//            if (queryResults.isEmpty()) {
//                return QueryResults.emptyResults();
//            }
//            Map<Long, String> userNicknameMap = repository.mapByIds(
//                    queryResults.getResults().stream()
//                            .flatMap(row -> Stream.of(row.getCreateUserId(), row.getUpdateUserId()))
//                            .filter(Objects::nonNull)
//                            .collect(Collectors.toSet())
//                    , QTabCodeExample.tabCodeExample.name
//            );
//            queryResults.getResults().forEach(row -> {
//                row.setCreateUserNickname(userNicknameMap.get(row.getCreateUserId()));
//                row.setUpdateUserNickname(userNicknameMap.get(row.getUpdateUserId()));
//            });
        }
        {
            final TabCodeExampleJpaExistsVO condition = new TabCodeExampleJpaExistsVO();
            QueryResults<TabCodeExampleJpaExistsVO> queryResults = repository.page(
                    condition
                    , Page.defaultPage()
                    , TabCodeExampleJpaExistsVO.class
//                    , TabCodeExample.allColumnAppends(
//                            QTabUser.tabUser.nickname
//                            , QTabUser.tabUser.phone
//                    )
            );
//            if (queryResults.isEmpty()) {
//                return QueryResults.emptyResults();
//            }
        }
    }

    public void demoRepository() {
        final QTabCodeExample table = QTabCodeExample.tabCodeExample;
        boolean exists = repository.exists(table.id.eq(1L)
                .and(table.deleted.eq(false))
        );
//        boolean exists1 = 1L == repository.count(table.id.eq(1L)
//                .and(table.deleted.eq(false))
//        );
//        boolean exists2 = repository.list(new TabCodeExample()).size() == 1L;

        long count = repository.count(IWhere.QdslWhere.of()
                .and(table.id.eq(1L))
                .and(exists, () -> table.deleted.eq(false))
                .toPredicate()
        );
    }


    public void listTest() {
        repository.listTest();
    }
}
